home *** CD-ROM | disk | FTP | other *** search
- /*================================================================================
- ReportError.c
-
- ©1991 Greg Anderson
- greggor@apple.com
-
- FREE DISTRIBUTION
-
- The possessor of this source code may use any portion of
- it for any purpose, and I place no restriction on its
- redistribution.
-
- These routines are very convenient for debugging; they will convert
- OSErrors from short negative numbers to human-readable strings in
- Pascal format
-
- This code depends on:
-
- StringUtilities.c
- DialogUtilities.c
-
- 'DLOG' resource ID 30303 A simple dialog box for displaying errors;
- 'DITL' resource ID 30303 Has one 'Okay' button and one static text
- item that reads:
-
- ^0 ^1
-
- ^2 because ^3
-
- 'TEXT' resource ID 30303 All error messages, each line cr-terminated
-
- ================================================================================*/
- #include "ReportError.h"
-
- /*
- // Header files for utility routines:
- */
- #ifndef __DIALOGUTILITIES__
- #include "DialogUtilities.h"
- #endif
- #ifndef __STRINGUTILITIES__
- #include "StringUtilities.h"
- #endif
- #ifndef _FAILUREHANDLER__
- #include "FailureHandler.h"
- #endif
- #ifndef __SHOWSTACKCHAIN__
- #include "ShowStackChain.h"
- #endif
-
- /*
- // Macintosh includes
- */
- #ifndef __TYPES__
- #include <Types.h>
- #endif
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
- #ifndef __MEMORY__
- #include <Memory.h>
- #endif
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
- #ifndef __PACKAGES__
- #include "Packages.h"
- #endif
-
- /*
- // MPW requires this, but Think C 4.0.5 won't compile if
- // it's in (but works all the same without it). The
- // error is 'Debug Table Overflow', & you can get it
- // just by including <Script.h> (which <Packages.h>
- // includes). It looks like a size problem, because
- // other files can include <Script.h> with no problem.
- //
- // MPW needs <Packages.h> for 'NumToString'.
- */
- #ifndef THINK_C
- #ifndef __PACKAGES__
- #include <Packages.h>
- #endif
- #endif
-
- Handle gResultCodeText = nil;
-
- /*----------------------------------------------------------------------
- Search for an error result code in the result code text
-
- Return 'false' if the name and description strings cannot be filled in
- ----------------------------------------------------------------------*/
- Boolean FindResultCodeDescription( OSErr theErr, Str255 errorNameStr, Str255 errorDescStr )
- {
- Size textSize;
- char* p;
- Boolean foundEntry;
- OSErr testError;
-
- /*
- // Note that if the error is a 'memFullErr', it isn't going to do
- // much good to try to load in the result code test. Handle this
- // case separately.
- //
- // While there are other situations that could also cause this
- // routine to fail, none are as common as memFullErr.
- */
- if( theErr == memFullErr )
- {
- CtoPcpy( errorNameStr, "memFullErr" );
- CtoPcpy( errorDescStr, "there is insufficient memory left in the heap zone" );
-
- return true;
- }
- /*
- // If we have never loaded the result code text, do so now
- */
- if( gResultCodeText == nil )
- gResultCodeText = GetResource( 'TEXT', kReportErrorID );
- if( gResultCodeText == nil )
- return false;
- /*
- // If the result code text has been purged, try to re-load it.
- */
- if( *gResultCodeText == nil )
- LoadResource( gResultCodeText );
- if( *gResultCodeText == nil )
- return false;
- /*
- // Lock the result text & dereference it
- */
- MoveHHi( gResultCodeText );
- HLock( gResultCodeText );
- p = *gResultCodeText;
- textSize = GetHandleSize( gResultCodeText );
- foundEntry = false;
- do
- {
- SkipToSpec( p, '-' );
- if( !(*p) )
- break;
- ++p;
-
- testError = -ScanNumberInString( &p );
- if( testError == theErr )
- {
- SkipPastWhitespace( p );
- ScanWordInString( &p, errorNameStr );
- SkipPastWhitespace( p );
- ScanLineInString( &p, errorDescStr );
- foundEntry = true;
- break;
- }
- }
- while( testError != -32767 );
- /*
- // Unlock the result text and return
- */
- HUnlock( gResultCodeText );
- return foundEntry;
- }
-
- /*----------------------------------------------------------------------
- Put up a dialog box reporting an error to the user
- ----------------------------------------------------------------------*/
- void ReportError( Str255 errorMsg, OSErr theErr )
- {
- DialogPtr dlog;
- short itemHit;
- Str255 errorNumberStr;
- Str255 errorNameStr;
- Str255 errorDescStr;
- long longErr = theErr;
-
- /*
- // Do nothing if theErr == noErr
- */
- if( theErr != noErr )
- {
- /*
- // Clear out the pascal strings, just to be safe
- */
- errorNameStr[0] = 0;
- errorDescStr[0] = 0;
- errorNumberStr[0] = 0;
- /*
- // Set up the error number string
- */
- NumToString( longErr, errorNumberStr );
- FindResultCodeDescription( theErr, errorNameStr, errorDescStr );
- if( errorDescStr[0] == 0 )
- CtoPcpy( errorDescStr, "an error ocurred" );
- /*
- // Set up Dialog box
- */
- dlog = GetNewDialog(kReportErrorID, (Ptr)0L, (WindowPtr)-1L);
- if( dlog != nil )
- {
- SetPort( dlog );
- ParamText( errorMsg, errorNumberStr, errorNameStr, errorDescStr );
- SelectWindow(dlog);
- InstallDefaultOutline( dlog, kReportErrorOK );
- if(!ExceptionNotifyProcInstalled())
- HideDItem(dlog,kReportErrorSC6);
- CenterAndShowDialog(dlog);
- InitCursor();
- /*
- // Wait for user to click "Okay" or "sc6"
- */
- do
- {
- ModalDialog((ModalFilterProcPtr) CutPasteFilter, &itemHit);
- } while( (itemHit != kReportErrorOK) && (itemHit != kReportErrorSC6) );
- DisposDialog(dlog);
- /*
- // If user hit 'sc6', then show the stack chain
- */
- if(itemHit == kReportErrorSC6)
- {
- ShowFailureStackChain("\pStack chain at time of failure (tracing A6 links):");
- }
- }
- else
- {
- DebugStr("\pReportError could not bring up dialog box");
- }
- }
- }
-